<?php
/**
 * Created by PhpStorm
 * User: lcz
 * Date: 2019/10/8
 * Time: 11:42
 * 队列任务
 */

namespace app\common\controller;

use app\admin\model\User;
use app\common\library\Redis;
use app\common\library\Weixin;
use app\common\model\AgentSendTips;
use app\common\model\AgentShop;
use app\common\model\AgentStock;
use app\common\model\Commission;
use app\common\model\History;
use app\common\model\Message;
use app\common\model\Order;
use app\common\model\OrderGoods;
use app\common\model\OrderGroup;
use app\common\model\QueueError;
use app\common\model\RuleSz;
use app\common\model\ShipRemind;
use app\common\service\OrderService;
use think\Controller;
use think\Db;
use think\Exception;
use think\exception\ErrorException;
use think\Log;

class Queue extends Controller
{
	
	
	/**
	 * 添加用户浏览记录
	 */
	public function addHistory($data)
	{
		$model = new History();
		$row = $model->where($data)->find();
		if ($row) {
			$res = $model->save([
				'number' => $row['number'] + 1,
				'status' => 1
			], $data);
		} else {
			$res = $model->isUpdate(false)
				->save($data);
		}
		
		return $res;
	}
	
	
	/**
	 * 添加队列任务
	 * @param $method
	 * @param $data
	 */
	public static function addTask($method, $data)
	{
		$redis = Redis::getInstance();
		$config = config('redis');
		$res = $redis->rPush($config['prefix'] . $config['name']['queue'], json_encode([
			'method' => $method,
			'data' => $data
		]));
		return $res;
	}
	
	
	/**
	 * 订单支付成功后的操作
	 * @param $data
	 * @return string
	 * @throws \think\db\exception\DataNotFoundException
	 * @throws \think\db\exception\ModelNotFoundException
	 * @throws \think\exception\DbException
	 */
	public function orderSuccess($data) {
		$id = $data['id'];
		
		$order = Db::name('order')->find($id);
		$goods = Db::name('orderGoods')->where(['order_id' => $id])->find();
		
		$model = new Order();
		$str = '订单ID【'.$id.'】';
		$model->startTrans();
		try {
			
			//待核销的订单
			if($order['status'] == $model::STATUS_SIGN || $order['status'] == $model::STATUS_WAIT_SHIPPING) {
				$serverObj = new OrderService();
				$successRes = $serverObj->rebate($id);
				if(!$successRes) {
					throw new Exception($serverObj->getError());
				}
			}
			
			
			//检测拼团状态
			if($order['status'] == $model::STATUS_GROUP && $order['group_id']) {
				$groupModel = new OrderGroup();

				$groupRes = $groupModel->changeNumber($order['group_id'], $goods);
				if(!$groupRes) {
					throw new Exception($groupModel->getError());
				}
			}
			
			$model->commit();
			$str .= '返利成功';
		} catch (Exception $e) {
			$model->rollback();
			$this->addError('orderSuccess', $data, '订单返利');
			$str .= '返利出错：'.$e->getMessage();
		} catch (\Exception $e) {
			$model->rollback();
			$this->addError('orderSuccess', $data, '订单返利');
			$str .= '返利出错：'.$e->getMessage();
		} catch (ErrorException $e) {
			$model->rollback();
			$this->addError('orderSuccess', $data, '订单返利');
			$str .= '返利出错：'.$e->getMessage();
		}
		
		return $str;
	}
	
	
	/**
	 * 添加执行错误的记录到数据库
	 * @param $method
	 * @param $data
	 * @param $name
	 */
	public function addError($method, $data, $name) {
		$model = new QueueError();
		$model->isUpdate(false)
			->save([
				'method' => $method,
				'data' => $data,
				'name' => $name
			]);
	}
	
	/**
	 * 发送模板消息
	 * @param $data
	 */
	public function sendTemplate($data) {
		$type = $data['type'];
		if($type == 'groupSuccess') {
			$groupId = $data['groupId'];
			$model = new OrderGroup();
			$res = $model->sendGroupTemplate($groupId, 'success');
		} elseif($type == 'groupFail') {
			$groupId = $data['groupId'];
			$model = new OrderGroup();
			$res = $model->sendGroupTemplate($groupId, 'fail');
		} else if($type == 'agentTips') {
			$model = new AgentShop();
			$res = $model->sendOrderTemplate($data['user_id'], $data['name']);
		} else if($type == 'applyTips') {
			$model = new AgentShop();
			$res = $model->sendApplyTemplate();
		}
		
		
		return $res;
	}
	
	/**
	 * 检测代理库存
	 */
	public function checkStock($data) {
		$shopId = $data['id'];
		$goodsId = $data['goods_id'];
		$specId = $data['spec_id'] ? : 0;
		$info = Db::name('agentShop')->find($shopId);
		
		$agentSetting = Db::name('agentStockSetting')
			->where(['goods_id' => $goodsId, 'spec_id' => $specId, 'agent_id' => $shopId])
			->find();
		
		$setting = Db::name('stockWarning')
			->where(['area' => $info['area'], 'level' => $info['role'], 'goods_id' => $goodsId, 'spec_id' => $specId])
			->find();
		
		$warningNumber = $agentSetting ? $agentSetting['warning_number'] : $setting['warning_number'];
		
		$str = $info['name'].'库存检测'.PHP_EOL;
		if(!$setting || $warningNumber <= 0) {
			return $str.='没有该库存预警设置';
		}
		
		$model = new AgentStock();
		$count = $model->getAgentAndSubStock($shopId, $goodsId, $specId);
		
		if($count['all_max_stock'] - $count['all_stock'] >= $count['warning_number']) {
			return $str .= '库存充足';
		}
		
		$number = $warningNumber;
		$goods = Db::name('agentStock')->alias('s')
			->join('goods g', 's.goods_id = g.id', 'left')
			->join('goodsSpec gs', 's.spec_id = gs.id', 'left')
			->where(['s.user_id' => $info['user_id'], 's.goods_id' => $goodsId, 's.spec_id' => $specId])
			->field('g.name as goods_name, gs.name as spec_name, s.number')
			->find();
		if(!$goods || $goods['number'] > $number) {
			return $str .= '没有需要提醒的库存';
		}
		
		//重庆场景店提醒给重庆提货点,深圳场景店提醒给火爆街
		//重庆提货点提醒给总部
		//深圳提货点和火爆街提醒给总部
		switch ($info['role']) {
			case User::LEVEL_SHOP:
				$pId = $info['area'] == User::AREA_OTHER ? $info['warehouse_id'] : $info['center_id'];
				break;
			default:
				$pId = '';
		}
		
		$userId = '';
		if($pId) {
			$pShop = AgentShop::get($pId);
			$pShop && $userId = $pShop['user_id'];
		} else {
			//发给总部
			$admin = User::get(['level' => User::LEVEL_HEADQUARTERS]);
			$admin && $userId = $admin['id'];
		}
		if($userId) {

			$tips ='您的下级【'.$info['name'].'】商品【'.$goods['spec_name'].$goods['goods_name'].'】库存为'.$goods['number'].',请及时发货!' ;
			
			$res = Message::add($userId, '发货提醒', $tips);
			$str .= '发货信息添加'.($res ? '成功' : '出错').PHP_EOL;
			
			$tipsRes = AgentSendTips::addRow($userId, $shopId, $goodsId, $specId);
			$str .= '发货提醒记录添加'.($tipsRes ? '成功' : '出错').PHP_EOL;

			$formIdRow = Db::name('formId')->alias('f')
				->join('user u', 'f.user_id = u.id', 'left')
				->where(['f.user_id' => $userId, 'number' => 0, 'create_time' => ['egt', strtotime('-7 days')]])
				->field('f.id, u.smallapp_openid, f.form_id')
				->find();
			if($formIdRow) {
				$config= config('weixin');
				$templateId = $config['smallapp']['message_template']['stock_warning'];
				$data = [
					'keyword1' => ['value' => $info['name']],
					'keyword2' => ['value' => $tips],
				];
				$obj = new Weixin($config['smallapp']['app_id']);
				$page = 'pages/index/index';
				$res = $obj->sendTemplate($formIdRow['smallapp_openid'], $templateId, $formIdRow['form_id'],$data, $page);
				if($res === true) {
					Db::name('formId')->where(['id' => $formIdRow['id']])->setInc('number');
					$str .= '模板发送成功'.PHP_EOL;
				} else {
					$str .= '模板发送出错'.PHP_EOL;
				}
			} else {
				$str .= '没有表单ID'.PHP_EOL;
			}
		}
		
		
		
		return $str;
		
	}
	
	/**
	 * 上级订单数量提醒
	 */
	public function agentOrderTips($data) {
		$orderId = $data['id'];
		$order = Db::name('order')->alias('o')
			->join('orderGoods og', 'o.id = og.order_id', 'left')
			->join('user u', 'o.user_id = u.id', 'left')
			->where(['o.id' => $orderId])
			->field('o.id, o.lat, o.lng, og.goods_info, o.number, u.recommend_user_id')
			->find();
		
		$str = '订单ID【'.$orderId.'】库存提醒'.PHP_EOL;
		$config = config('agent');
		//大于数量才提醒
		if($order['number'] >= $config['order']['start']) {
			$agent = null;
			if($order['lat'] && $order['lng']) {
				//有坐标的给最近的发提醒
				$agent = Db::name('agentShop')
					->where(['role' => User::LEVEL_WAREHOUSE])
					->field('id, name, image, content, lat, lng, address, ROUND(6378.138 * 2 * ASIN(SQRT( POW( SIN( ('.$order['lat'].' * PI() / 180 - lat * PI() / 180) / 2),2) + COS('.$order['lat'].' * PI() / 180) * COS(lat * PI() / 180) * POW( SIN(('.$order['lng'].' * PI() / 180 - lng * PI() / 180 ) / 2 ),  2))) * 1000) AS distance')
					->order('distance asc')
					->find();
				
			} else if ($order['recommend_user_id']) {
				//如果有推荐人，且推荐人是代理，给代理的提货点或发展中心提醒
				$agentWhere = [
					'user_id' => $order['recommend_user_id'],
					'role' => User::LEVEL_WAREHOUSE
				];
				
				$agent = Db::name('agentShop')->where($agentWhere)->find();
			}
			
			//如果有提货点信息
			if($agent) {
				$goodsInfo = json_decode($order['goods_info'], true);
				$tipsInfo = '你附近有用户购买了【'.$goodsInfo['spec_name'] ? $goodsInfo['spec_name'] : $goodsInfo['name'].'】,数量【'.$order['number'].'】瓶，请注意备货!';
				if($order['number'] < $config['order']['warehouse']) {
					//给提货点发消息
					
					Message::add($agent['user_id'], '下单提醒', $tipsInfo);
					self::addTask('sendTemplate',[
						'type' => 'agentTips',
						'name' => $tipsInfo,
						'user_id' => $agent['user_id']
					]);
					
					return $str .= '没有找到提货点'.PHP_EOL;
				} else if($agent['center_id']) {
					//给提货点的上级发消息
					$center = AgentShop::get($agent['center_id']);
					Message::add($center['user_id'], '下单提醒', $tipsInfo);
					self::addTask('sendTemplate',[
						'type' => 'agentTips',
						'name' => $tipsInfo,
						'user_id' => $agent['user_id']
					]);
					return $str .= '没有找到发展中心'.PHP_EOL;
				}
				
				return $str .= '没有找到提货点'.PHP_EOL;
				
			} else {
				return $str .= '没有找到提货点'.PHP_EOL;
			}
		} else {
			return $str .= '数量不满足'.PHP_EOL;
		}
	}
	
	public function checkActivityGift($data) {
		$id = $data['id'];
		$orderModel = new Order();
		$order = $orderModel->find($id);
		
		if($order['order_type'] != $orderModel::TYPE_NORMAL && $order['order_type'] != $orderModel::TYPE_GROUP) {
			return true;
		}
		
		$item = OrderGoods::get(['order_id' => $id]);
		$goodsId = $item['goods_id'];
		$activity = Db::name('activityGift')
			->where('FIND_IN_SET('.$goodsId.', goods_ids)')
			->where('start_time', '<=', time())
			->where('end_time', '>', time())
			->where('buy_number', '<=', $item['number'])
			->find();
		
		if(!$activity) {
			Log::info('没有满足的活动');
			return true;
		}
		
		// 赠送的数量
		
		$giftNumber = floor($item['number']/$activity['buy_number']);
		//添加订单
		try {
			$orderRes = $orderModel->addRewardOrder($order['user_id'], $giftNumber, $activity['goods_id'], $activity['spec_id'], $orderModel::TYPE_REWARD, $order['area'], '活动赠送商品');
			
			if($orderRes) {
				throw new Exception($orderModel->getError());
			}
			$orderModel->commit();
			Log::info('success '.$id);
			
		} catch (Exception $e) {
			$orderModel->rollback();
			Log::info('error '.$e->getMessage());
		}
	}
	
	
}
